/*
 * UtilsJNI.cpp
 *
 *  Created on: 24/10/2011
 *      Author: faust
 */

#include "UtilsJNI.h"
#include "SampleUtils.h"

jint UtilsJNI::getJavaInt(JNIEnv* env, jobject object, string functionName, string logMsg)
{
	string errMsg;
	// Handle to the Java Model3D class:
	jclass objectClass = env->GetObjectClass(object);

	/* Get data: */
	jmethodID methodId = env->GetMethodID(objectClass , functionName.data(), "()I");
	if (!methodId)
	{
		errMsg = logMsg + " (NDK) - Function " + functionName + "() not found.";
		LOG(errMsg.data());
		return 0;
	}

	jint res = (jint)env->CallObjectMethod(object, methodId);
	if (res == 0)
	{
		errMsg = logMsg + " (NDK) - " + functionName + "() function returned zero pointer";
		LOG(errMsg.data());
		return 0;
	}

	return res;
}

jint UtilsJNI::getJavaFloat(JNIEnv* env, jobject object, string functionName, string logMsg)
{
	string errMsg;
	// Handle to the Java Model3D class:
	jclass objectClass = env->GetObjectClass(object);

	/* Get data: */
	jmethodID methodId = env->GetMethodID(objectClass , functionName.data(), "()F");
	if (!methodId)
	{
		errMsg = logMsg + " (NDK) - Function " + functionName + "() not found.";
		LOG(errMsg.data());
		return 0;
	}

	jfloat res = (jfloat)env->CallFloatMethod(object, methodId);
	if (res == 0)
	{
		errMsg = logMsg + " (NDK) - " + functionName + "() function returned zero pointer";
		LOG(errMsg.data());
		return 0;
	}

	return res;
}

jfloat* UtilsJNI::getJavaFloatArray(JNIEnv* env, jobject object, string functionName, string logMsg)
{
	string errMsg;

	jclass objectClass = env->GetObjectClass(object);

	/* Get buffer data: */
	jmethodID methodId = env->GetMethodID(objectClass , functionName.data(), "()[F");
	if (!methodId)
	{
		errMsg = logMsg + " (NDK) - Function " + functionName + "() not found.";
		LOG(errMsg.data());
		return 0;
	}

	jfloatArray floatBuffer = (jfloatArray)env->CallObjectMethod(object, methodId);
	if (floatBuffer == NULL)
	{
		errMsg = logMsg + " (NDK) - " + functionName + "() function returned zero pointer";
		LOG(errMsg.data());
		return 0;
	}

	jsize bufferLength = env->GetArrayLength(floatBuffer);
	jfloat *body = env->GetFloatArrayElements(floatBuffer, 0);
	if (body == NULL)
	{
		errMsg = logMsg + " (NDK) - Failed to get the buffer array";
		LOG(errMsg.data());
		return 0;
	}

	//copy the buffer: TODO: wouldn't be better to use memcpy?
	float* buffer = new float[bufferLength];
	for (int v=0; v < bufferLength; v++)
	{
		buffer[v] = body[v];
	}

	//Release the shared memory between Java and C++
	env->ReleaseFloatArrayElements(floatBuffer, body, 0);

	return buffer;
}

jint* UtilsJNI::getJavaIntArray(JNIEnv* env, jobject object, string functionName, string logMsg)
{
	string errMsg;

	jclass objectClass = env->GetObjectClass(object);

	/* Get buffer data: */
	jmethodID methodId = env->GetMethodID(objectClass , functionName.data(), "()[I");
	if (!methodId)
	{
		errMsg = logMsg + " (NDK) - Function " + functionName + "() not found.";
		LOG(errMsg.data());
		return 0;
	}

	jintArray intBuffer = (jintArray)env->CallObjectMethod(object, methodId);
	if (intBuffer == NULL)
	{
		errMsg = logMsg + " (NDK) - " + functionName + "() function returned zero pointer";
		LOG(errMsg.data());
		return 0;
	}

	jsize bufferLength = env->GetArrayLength(intBuffer);
	jint *body = env->GetIntArrayElements(intBuffer, 0);
	if (body == NULL)
	{
		errMsg = logMsg + " (NDK) - Failed to get the buffer array";
		LOG(errMsg.data());
		return 0;
	}

	//copy the buffer: TODO: wouldn't be better to use memcpy?
	int* buffer = new int[bufferLength];
	for (int v=0; v < bufferLength; v++)
	{
		buffer[v] = body[v];
	}

	//Release the shared memory between Java and C++
	env->ReleaseIntArrayElements(intBuffer, body, 0);

	return buffer;
}
